home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / gsview / src / gsv16spl.c < prev    next >
C/C++ Source or Header  |  1995-11-23  |  10KB  |  367 lines

  1. /* Copyright (C) 1995, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gsv16spl.c */
  19. /* 16-bit access to print spooler from Win32s */
  20. /* by Russell Lang */
  21. /* 1995-11-10 */
  22.  
  23. /* 
  24.  * GSview and Ghostscript produce printer specific output
  25.  * which must be given to the print spooler.
  26.  * Under Win16, the APIs OpenJob, WriteSpool etc. are used
  27.  * Under Win32 and Windows 95/NT, the APIs OpenPrinter, WritePrinter etc.  
  28.  * are used.
  29.  * Under Win32s, the 16-bit spooler APIs are not available, and the
  30.  * 32-bit spooler APIs are not implemented.
  31.  * This purpose of this application is to provide a means for the Win32s
  32.  * versions of GSview and Ghostscript to send output to the 16-bit spooler.
  33.  */
  34.  
  35. /*
  36.  * Usage:  gsv16spl hwnd
  37.  *   hwnd is the window handle of the program starting gsv16spl
  38.  *
  39.  * hwnd will be sent a WM_USER+1=WM_GSV16SPL message with the window 
  40.  * handle of gsv16spl in the lParam.
  41.  * gsv16spl is then called using SendMessage with the handle of
  42.  * a global shareable memory block in lParam.
  43.  * The first SendMessage should have the null terminated name of the 
  44.  * printer port  in this memory block.
  45.  * Subsequent memory blocks contain data to be sent to that port.
  46.  * The memory block contains a length count in the first WORD,
  47.  * followed by the actual data.
  48.  * A length count of 0 indicates EOF.  This will cause gsv16spl 
  49.  * to close the print job and exit.
  50.  * A length count of -1 indicates an error.  gsv16spl will abort
  51.  * the print job and exit.
  52.  */
  53.  
  54.  
  55. #define STRICT
  56. #include <windows.h>
  57. /* #include <string.h> */
  58. #include <stdlib.h>
  59.  
  60. /* documented in Device Driver Adaptation Guide */
  61. /* Prototypes taken from print.h */
  62. DECLARE_HANDLE(HPJOB);
  63.  
  64. HPJOB   WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
  65. int     WINAPI StartSpoolPage(HPJOB);
  66. int     WINAPI EndSpoolPage(HPJOB);
  67. int     WINAPI WriteSpool(HPJOB, LPSTR, int);
  68. int     WINAPI CloseJob(HPJOB);
  69. int     WINAPI DeleteJob(HPJOB, int);
  70. int     WINAPI WriteDialog(HPJOB, LPSTR, int);
  71. int     WINAPI DeleteSpoolPage(HPJOB);
  72.  
  73. HPJOB hJob;
  74. unsigned long bytes_written;
  75. char portname[64];
  76. POINT char_size;
  77. HWND hwndspl;
  78. HWND hwndnotify;    /* window handle of caller */
  79. HICON hiconspl;
  80. HINSTANCE phInstance;
  81.  
  82. #define ID_GSV16SPL 42
  83. #define IDC_ABOUT  200
  84. #define WM_GSV16SPL WM_USER+1
  85. #define WINDOWWIDTH    (36*char_size.x)
  86. #define WINDOWHEIGHT    ( 5*char_size.y)
  87. char szAppName[] = "GS Win32s/Win16 spooler";
  88. char debug_str[64];
  89.  
  90. void
  91. draw_text(HWND hwnd, HDC hdc)
  92. {
  93.     char buf[256];
  94.     RECT rect;
  95.     int x, y;
  96.     GetClientRect(hwnd, &rect);
  97.     x = 3 * char_size.x + 32;
  98.     y = (rect.bottom - rect.left - char_size.y) / 2;
  99.  
  100.     SetTextAlign(hdc, TA_LEFT | TA_TOP);
  101.     if (hwndnotify) {
  102.     wsprintf(buf, "%lu bytes written to %s", bytes_written, (LPSTR)portname);
  103.     TextOut(hdc, x, y, buf, lstrlen(buf));
  104.     if (debug_str)
  105.         TextOut(hdc, x, y + char_size.y, debug_str, lstrlen(debug_str));
  106.     }
  107.     else {
  108.     lstrcpy(buf, "Playing Russian Roulette are we?");
  109.     TextOut(hdc, x, y - char_size.y, buf, lstrlen(buf));
  110.     lstrcpy(buf, "GSV16SPL is called automatically");
  111.     TextOut(hdc, x, y, buf, lstrlen(buf));
  112.     lstrcpy(buf, "from GSview or Ghostscript.");
  113.     TextOut(hdc, x, y + char_size.y, buf, lstrlen(buf));
  114.     }
  115. }
  116.  
  117. int
  118. open_printer(LPSTR port)
  119. {
  120.     lstrcpy(portname, port);
  121.     hJob = OpenJob(port, szAppName, (HDC)NULL);
  122.     switch ((int)hJob) {
  123.     case SP_APPABORT:
  124.     case SP_ERROR:
  125.     case SP_OUTOFDISK:
  126.     case SP_OUTOFMEMORY:
  127.     case SP_USERABORT:
  128.         hJob = NULL;
  129.         lstrcpy(debug_str, "OpenJob failed");
  130.         return FALSE;
  131.     }
  132.     if (StartSpoolPage(hJob) < 0) {
  133.     lstrcpy(debug_str, "StartSpoolPage failed");
  134.         DeleteJob(hJob, 0);
  135.         hJob = NULL;
  136.     return FALSE;
  137.     }
  138.     return TRUE;    /* OK */
  139. }
  140.  
  141. int
  142. close_printer(void)
  143. {    
  144.     if (hJob == (HPJOB)NULL)
  145.     return FALSE;
  146.     EndSpoolPage(hJob);
  147.     CloseJob(hJob);
  148.     hJob = NULL;
  149.     return TRUE;
  150. }
  151.  
  152. int
  153. abort_printer(void)
  154. {
  155.     if (hJob == (HPJOB)NULL)
  156.     return FALSE;
  157.     EndSpoolPage(hJob);
  158.     DeleteJob(hJob, 0);
  159.     hJob = NULL;
  160.     return TRUE;
  161. }
  162.  
  163. int
  164. write_printer(LPSTR data, WORD length)
  165. {
  166.     if (hJob == (HPJOB)NULL)
  167.     return FALSE;
  168.     if (WriteSpool(hJob, data, length) < 0) {
  169.     lstrcpy(debug_str, "WriteSpool failed");
  170.     abort_printer();
  171.         return FALSE;
  172.     }
  173.     return TRUE;
  174. }
  175.  
  176. int
  177. process_block(HGLOBAL hmem)
  178. {
  179. LPBYTE lpbyte;
  180. WORD length;
  181. int rc;
  182.     if (hmem == (HGLOBAL)NULL) {
  183.     lstrcpy(debug_str, "hglobal is null");
  184.     return FALSE;
  185.     }
  186.     lpbyte = GlobalLock(hmem);
  187.     if (lpbyte == (LPBYTE)NULL) {
  188.     lstrcpy(debug_str, "Couldn't lock hglobal");
  189.     return FALSE;
  190.     }
  191.     length = *(LPWORD)lpbyte;
  192.     if (length == 0) {
  193.     /* EOF */
  194.     lstrcpy(debug_str, "Got EOF");
  195.     GlobalUnlock(hmem);
  196.     PostQuitMessage(0);
  197.     return close_printer();
  198.     }
  199.     else if (length == 0xffff) {
  200.     /* Abort */
  201.     lstrcpy(debug_str, "Got Abort");
  202.     GlobalUnlock(hmem);
  203.     PostQuitMessage(0);
  204.     return abort_printer();
  205.     }
  206.  
  207.     if (hJob) {
  208.     HDC hdc;
  209.     rc = write_printer((LPSTR)(lpbyte+2), length); 
  210.     bytes_written += length;
  211.     hdc = GetDC(hwndspl);
  212.     draw_text(hwndspl, hdc);
  213.     ReleaseDC(hwndspl, hdc);
  214.     }
  215.     else {
  216.     rc = open_printer((LPSTR)(lpbyte+2));
  217.     }
  218.     GlobalUnlock(hmem);
  219.     return rc;
  220. }
  221.  
  222. /* copyright dialog box */
  223. BOOL CALLBACK _export
  224. AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  225. {
  226.     switch(message) {
  227.         case WM_COMMAND:
  228.             switch(LOWORD(wParam)) {
  229.                 case IDOK:
  230.                     EndDialog(hDlg, TRUE);
  231.                     return(TRUE);
  232.                 default:
  233.                     return(FALSE);
  234.             }
  235.         default:
  236.             return(FALSE);
  237.     }
  238. }
  239.  
  240. void
  241. show_about(void)
  242. {
  243.     DLGPROC lpProcAbout;
  244.     lpProcAbout = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, phInstance);
  245.     DialogBoxParam( phInstance, "AboutDlgBox", hwndspl, lpProcAbout, (LPARAM)NULL);
  246.     FreeProcInstance((FARPROC)lpProcAbout);
  247. }
  248.  
  249.  
  250. /* Window Procedure */
  251. LRESULT CALLBACK _export
  252. WndSplProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  253. {
  254. HMENU hmenu;
  255. PAINTSTRUCT ps;
  256. HDC hdc;
  257. RECT rect;
  258.     switch(message) {
  259.     case WM_GSV16SPL:
  260.         /* we have been called using SendMessage so we */
  261.         /* must not do anything that requires the message queue */
  262.         return process_block((HGLOBAL)lParam);
  263.     case WM_PAINT:
  264.         hdc = BeginPaint(hwnd, &ps);
  265.         draw_text(hwnd, hdc);
  266.         GetClientRect(hwnd, &rect);
  267.         DrawIcon(hdc, char_size.x, (rect.bottom-rect.top-32)/2, hiconspl);
  268.         EndPaint(hwnd, &ps);
  269.         return 0;
  270.     case WM_CREATE:
  271.         hmenu = GetSystemMenu(hwnd,FALSE);
  272.         EnableMenuItem(hmenu, SC_SIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  273.         EnableMenuItem(hmenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  274.         AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
  275.         AppendMenu(hmenu, MF_ENABLED, IDC_ABOUT, "&About");
  276.         break;
  277. /*    case WM_CLOSE:   */
  278.     case WM_DESTROY:
  279.         PostQuitMessage(0);
  280.         break;
  281.     case WM_SYSCOMMAND:
  282.             switch(LOWORD(wParam)) {
  283.             case IDC_ABOUT:
  284.             show_about();
  285.             return 0;
  286.         }
  287.         break;
  288.     }
  289.     return DefWindowProc(hwnd, message, wParam, lParam);
  290. }
  291.  
  292.  
  293. void
  294. init_window(void)
  295. {
  296. int i;
  297. WNDCLASS wndclass;
  298. HDC hdc;
  299. TEXTMETRIC tm;
  300. HFONT hfont;
  301.  
  302.     /* register the window class */
  303.     wndclass.style = 0;
  304.     wndclass.lpfnWndProc = WndSplProc;
  305.     wndclass.cbClsExtra = 0;
  306.     wndclass.cbWndExtra = 0;
  307.     wndclass.hInstance = phInstance;
  308.     wndclass.hIcon = hiconspl = LoadIcon(phInstance, MAKEINTRESOURCE(ID_GSV16SPL));
  309.     wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  310.     wndclass.hbrBackground =  GetStockObject(WHITE_BRUSH);
  311.     wndclass.lpszMenuName = NULL;
  312.     wndclass.lpszClassName = szAppName;
  313.     RegisterClass(&wndclass);
  314.  
  315.     hdc = GetDC(NULL);  /* desktop */
  316.     hfont = GetStockObject(SYSTEM_FIXED_FONT);
  317.     SelectObject(hdc, hfont);
  318.     GetTextMetrics(hdc, (LPTEXTMETRIC)&tm);
  319.     ReleaseDC(NULL, hdc);
  320.     char_size.x = tm.tmAveCharWidth;
  321.     char_size.y = tm.tmHeight;
  322.  
  323.     hwndspl = CreateWindow(szAppName, (LPSTR)szAppName,
  324.           WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
  325. /*
  326.           CW_USEDEFAULT, CW_USEDEFAULT, 
  327. */
  328. 0,0,
  329.           WINDOWWIDTH, WINDOWHEIGHT,
  330.           NULL, NULL, phInstance, (void FAR *)NULL);
  331.  
  332.     return;
  333. }
  334.  
  335. int PASCAL 
  336. WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
  337. {
  338.     MSG msg;
  339.     phInstance = hInstance;
  340.  
  341.     /* find out window handle of caller */
  342.     if (lpszCmdLine[0] != '\0') {
  343.         char buf[64];
  344.         lstrcpyn(buf, lpszCmdLine, sizeof(buf)-1);
  345.         hwndnotify = (HWND)atoi(buf);
  346.     }
  347.     else {
  348.         hwndnotify = (HWND)NULL;
  349.     }
  350.  
  351.     init_window();
  352.     ShowWindow(hwndspl, cmdShow);
  353.  
  354.     /* notify caller about our window handle */
  355.     if (hwndnotify)
  356.         SendMessage(hwndnotify, WM_GSV16SPL, 0, (LPARAM)hwndspl);
  357.  
  358.     while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
  359.         TranslateMessage(&msg);
  360.         DispatchMessage(&msg);
  361.     }
  362.  
  363.     DestroyWindow(hwndspl);
  364.     return 0;
  365. }
  366.  
  367.